home *** CD-ROM | disk | FTP | other *** search
- Path: newshost.centrum.is!news
- From: bjarnir@centrum.is (Bjarni Ragnarsson)
- Newsgroups: comp.lang.c++
- Subject: Re: How do you return values from in-line asm?
- Date: 29 Mar 1996 17:35:42 GMT
- Organization: BR Software
- Message-ID: <4jh71e$iq8@newshost.centrum.is>
- References: <4j9mab$19si@usenetp1.news.prodigy.com>
- NNTP-Posting-Host: tungl-48.centrum.is
- X-Newsreader: WinVN version 0.82
-
- In article <4j9mab$19si@usenetp1.news.prodigy.com>, XKWR65B@prodigy.com (Mark Rubelmann) says:
- >
- >
- >Hey there! I got this book that is about programming games in C but I
- >have Borland C++ v3.0 and some of the stuff doesn't work quite right.
- >Most of the things I have been able to figure out on my own but I'm
- >having trouble returning values from an inline assembly function. Here's
- >the code that's in the book:
- >
- >unsigned char Get_Scan_Code(void)
- >{
- >asm {
- > mov ah,01h //Function 1: is a key ready?
- > int 16h // Call interrupt
- > jz empty // No key, exit
- > mov ah,00h // Function 0: get scan code
- > int 16h // Call interrupt
- > mov al,ah // result was in ah so put it in al
- > xor ah,ah // zero out ah
- > jmp done // the data's in ax (??? ax???)
- >
- >empty:
- > xor ax,ax // clear out ax, 0 means no key
- >done:
- > }
- >}
- >
- >
- >First of all, I just don't understand how the resut went from al to ax.
- >Also, I know the line labels should be outside of the asm statement but
- >that's the way it was in the book. I've tried fooling around with ret and
- >stuff like that but I can't get it to work. The compiler always gives a
- >warning that it should return a value. When I try to use the function in
- >something like:
- >
- > while(Get_Scan_Code==0) {}
- >
- >but it doesn't work, it just goes on to the next statement. Any help
- >would be appreciated.
- >
- >
-
- First of all, "ax" is a two-byte register. The high-byte is "ah" and the low byte is "al".
- Any changes to ax affects either al, ah or both and vice versa.
- The same goes for BX=BH BL and CX=CL CH etc....
-
- In the code, al is set to ah and ah then set to Zero. That is, the high byte of ax is
- copied to the low byte and the high byte is then zeroed.
-
-
- As to the labels, I believe inline labels in Borland can only be C labels, and thus
- must be declared outside the asm block. The asm code can use them just the
- same, with the exeption that it must be within the same function. The compiler
- decides weather pointers are FAR or SHORT.
-
- Note that the code returns the scan-code in register ax (the low byte, al).
- For the function to returna value that value must be placed in a specific address
- (if I remember correctly).
-
- The easiest and probably the most efficient way to handle this is to let the compiler
- do the job for you. Simply add
-
- return _AL;
-
- at the end of the function (outside the asm block). This returns the value in register
- al. Note that the function returns unsigned char which is one byte. AX is two bytes.
-
- _AL (_AX, _AH etc.) are register pseudovariables in Borland C++.
-
- Can't see at a glance the use of setting ax as only half of it iss needed.
- Perhaps this is a part of a code which needs ax to be set.
-
- The suggested code:
-
- unsigned char Get_Scan_Code(void)
- {
- asm {
- mov ah,01h //Function 1: is a key ready?
- int 16h // Call interrupt
- jz empty // No key, exit
- mov ah,00h // Function 0: get scan code
- int 16h // Call interrupt
- // Don't let's copy ah to al. Let's use ah directly.
- // Don't zero out ah or al as we only use ah to return a value.
- jmp done // the data's in ah
- }
-
- empty: // Keep label outside block.
- asm xor ah,ah // clear out ah, 0 means no key
- done:
-
- return _AH; // ah is returned instead of ax.
-
- }
-
- Hope this is of some help,
- Bjarni Ragnarsson
- bjarnir@centrum.is
-
-
-
-
-
-